# -*- coding: utf-8 -*-

import json
import logging
from functools import wraps
from odoo import http
from odoo.http import request

_logger = logging.getLogger(__name__)


def api_response(func):
    """API响应装饰器，统一处理响应格式和错误"""
    @wraps(func)
    def wrapper(*args, **kwargs):
        try:
            # 设置响应头
            if request.httprequest.method == 'OPTIONS':
                # 处理预检请求
                response = request.make_response('')
                response.headers['Access-Control-Allow-Origin'] = '*'
                response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'
                response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization, X-Requested-With'
                response.headers['Access-Control-Max-Age'] = '86400'
                return response
            
            result = func(*args, **kwargs)
            
            # 如果结果已经是完整的响应格式，直接返回
            if isinstance(result, dict) and 'code' in result:
                response = request.make_response(
                    json.dumps(result, ensure_ascii=False),
                    headers=[('Content-Type', 'application/json; charset=utf-8')]
                )
            else:
                # 包装成标准格式
                response_data = {
                    'code': 200,
                    'msg': '操作成功',
                    'data': result
                }
                response = request.make_response(
                    json.dumps(response_data, ensure_ascii=False),
                    headers=[('Content-Type', 'application/json; charset=utf-8')]
                )
            
            # 添加CORS头
            response.headers['Access-Control-Allow-Origin'] = '*'
            response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'
            response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization, X-Requested-With'
            
            return response
            
        except Exception as e:
            _logger.error(f"API调用异常: {str(e)}", exc_info=True)
            error_response = {
                'code': 500,
                'msg': f'服务器内部错误: {str(e)}',
                'data': None
            }
            response = request.make_response(
                json.dumps(error_response, ensure_ascii=False),
                headers=[('Content-Type', 'application/json; charset=utf-8')]
            )
            response.headers['Access-Control-Allow-Origin'] = '*'
            return response
    
    return wrapper


def verify_api_token(func):
    """API token验证装饰器"""
    @wraps(func)
    def wrapper(*args, **kwargs):
        try:
            import jwt
            
            # 获取token
            auth_header = request.httprequest.headers.get('Authorization')
            if not auth_header:
                _logger.error("请求缺少 Authorization header")
                return {
                    'code': 401,
                    'msg': '缺少访问令牌',
                    'data': None
                }
            
            if not auth_header.startswith('Bearer '):
                _logger.error(f"Authorization header 格式错误: {auth_header}")
                return {
                    'code': 401,
                    'msg': '令牌格式错误',
                    'data': None
                }
            
            token = auth_header.split(' ')[1]
            _logger.info(f"token: {token}")
            
            # 验证token
            try:
                config_model = request.env['device.api.config'].sudo()
                _logger.info(f"config_model: {config_model}")
                secret_key = config_model.get_jwt_secret()
                _logger.info(f"secret_key: {secret_key}")
            except Exception as config_error:
                _logger.error(f"获取JWT密钥失败: {str(config_error)}", exc_info=True)
                return {
                    'code': 500,
                    'msg': '配置错误',
                    'data': None
                }
            try:
                payload = jwt.decode(token, secret_key, algorithms=['HS256'])
                _logger.info(f"payload: {payload}")
                user_id = payload.get('user_id')
                
                # 检查 user_id 是否有效
                if not user_id:
                    return {
                        'code': 401,
                        'msg': '无效的访问令牌',
                        'data': None
                    }
                
                # 获取用户
                user = request.env['device.user'].sudo().browse(int(user_id))
                if not user.exists():
                    return {
                        'code': 401,
                        'msg': '用户不存在',
                        'data': None
                    }
                
                # 检查用户状态：status='0'表示正常，'1'表示停用
                if user.status != '0':
                    return {
                        'code': 401,
                        'msg': '用户已停用',
                        'data': None
                    }
                
                # 检查删除标志：del_flag='0'表示存在，'2'表示删除
                if user.del_flag != '0':
                    return {
                        'code': 401,
                        'msg': '用户已删除',
                        'data': None
                    }
                
                # 确保用户记录是有效的单个记录
                user.ensure_one()
                
                # 先切换请求环境到该用户，再使用新环境重新获取用户记录，避免旧env造成的空用户/权限问题
                try:
                    request.update_env(user=user.id)
                    _logger.info(f"update_env to user={user.id}, env.user.id={request.env.user.id}")
                except Exception as env_err:
                    _logger.error(f"update_env 切换失败: {env_err}")
                
                # 使用更新后的env重新browse，确保记录绑定到当前env，避免后续计算字段访问到错误的env
                try:
                    user = request.env['device.user'].browse(int(user_id))
                    user.ensure_one()
                except Exception as re_browse_err:
                    _logger.error(f"切换env后重新获取用户失败: {re_browse_err}")
                    return {
                        'code': 401,
                        'msg': '用户上下文切换失败',
                        'data': None
                    }
                
                # 存储到request供后续使用（如部门权限装饰器）
                request.api_user = user
                
            except jwt.ExpiredSignatureError:
                return {
                    'code': 401,
                    'msg': '访问令牌已过期',
                    'data': None
                }
            except jwt.InvalidTokenError:
                return {
                    'code': 401,
                    'msg': '无效的访问令牌',
                    'data': None
                }
            
            return func(*args, **kwargs)
            
        except Exception as e:
            _logger.error(f"Token验证异常: {str(e)}", exc_info=True)
            return {
                'code': 500,
                'msg': f'Token验证失败: {str(e)}',
                'data': None
            }
    
    return wrapper


def check_api_permission(permission_code):
    """API按钮权限检查装饰器（已注释，保留方法）"""
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            # 检查用户是否有权限
            user = getattr(request, 'api_user', None)
            if not user:
                return {
                    'code': 401,
                    'msg': '用户未登录',
                    'data': None
                }
            
            # 检查按钮权限（已注释，改用部门权限）
            # if not user.check_user_permissions(permission_code):
            #     return {
            #         'code': 403,
            #         'msg': '没有权限访问',
            #         'data': None
            #     }
            
            return func(*args, **kwargs)
        return wrapper
    return decorator


def check_department_permission(func):
    """部门权限检查装饰器"""
    @wraps(func)
    def wrapper(*args, **kwargs):
        # 检查用户是否有权限
        user = getattr(request, 'api_user', None)
        if not user:
            return {
                'code': 401,
                'msg': '用户未登录',
                'data': None
            }
        
        # 确保用户是单个记录而不是空记录集
        if not user.exists():
            return {
                'code': 401,
                'msg': '用户不存在',
                'data': None
            }
        
        # 重新从当前环境获取用户记录，确保绑定到正确的环境，避免计算字段访问错误的env
        try:
            current_user = request.env['device.user'].browse(user.id)
            current_user.ensure_one()
        except Exception as e:
            _logger.error(f"重新获取用户记录失败: {str(e)}", exc_info=True)
            return {
                'code': 401,
                'msg': '用户上下文错误',
                'data': None
            }
        
        # 部门权限校验逻辑
        # admin账号拥有全部权限
        # 部门负责人可看到该部门下全部设备以及设备相关的
        # 不是负责人则只能看到设备绑定的用户
        
        # 将当前用户信息存储到request，供后续方法使用
        request.current_api_user = current_user
        
        return func(*args, **kwargs)
    return wrapper


class APIBaseController(http.Controller):
    """API基础控制器"""
    
    def verify_token(self):
        """验证JWT token"""
        try:
            import jwt
            auth_header = request.httprequest.headers.get('Authorization')
            if not auth_header or not auth_header.startswith('Bearer '):
                return None
            
            token = auth_header.split(' ')[1]
            try:
                config_model = request.env['device.api.config'].sudo()
                secret_key = config_model.get_jwt_secret()
            except Exception:
                return None
            payload = jwt.decode(token, secret_key, algorithms=['HS256'])
            
            user_id = payload.get('user_id')
            if not user_id:
                return None
                
            user = request.env['device.user'].sudo().browse(int(user_id))
            if user.exists():
                # 检查用户状态：status='0'表示正常，del_flag='0'表示存在
                if user.status == '0' and user.del_flag == '0':
                    return user
            return None
        except:
            return None
    
    def check_permission(self, permission_code):
        """检查权限"""
        user = self.verify_token()
        if not user:
            return False
        if user.is_admin:
            return True
        return user.check_user_permissions(permission_code)
    
    def success_response(self, data=None, msg='操作成功'):
        """成功响应"""
        return {
            'code': 200,
            'msg': msg,
            'data': data
        }
    
    def error_response(self, msg='操作失败', code=500, data=None):
        """错误响应"""
        return {
            'code': code,
            'msg': msg,
            'data': data
        }
    
    def paginate_response(self, records, page_num=1, page_size=10, total=None):
        """分页响应"""
        if total is None:
            total = len(records)
        
        return {
            'code': 200,
            'msg': '查询成功',
            'data': {
                'total': total,
                'rows': records,
                'pageNum': page_num,
                'pageSize': page_size
            }
        }
